import queue
import socket
import threading
import time
import uuid  # 用于生成客户端唯一标识
from datetime import datetime

import ttkbootstrap as ttkb
from ttkbootstrap.constants import *
from ttkbootstrap.scrolled import ScrolledText

from app.util.annotation_util import annotate, ClassInfo
from app.view.base_view import View


@annotate(ClassInfo(name="TCP工具", category="tool"))
class NetView(View):
    """设置视图"""

    def __init__(self, parent, controller):
        super().__init__(parent, controller)
        # 网络相关变量
        self.socket = None
        self.is_connected = False  # 客户端连接状态
        self.is_running = False  # 服务器运行状态
        self.receive_queue = queue.Queue()
        self.send_timer = None
        self.is_sending_periodically = False

        # 客户端连接管理（服务器模式）
        self.clients = {}  # {client_id: (socket, address, connect_time)}
        self.client_lock = threading.Lock()
        self.selected_client = None  # 当前选中的客户端ID

        # 创建主布局
        self._create_main_layout()

        # 启动接收队列检查
        self._check_receive_queue()

    def _create_main_layout(self):
        """创建主界面布局"""
        # 顶部配置区域
        config_frame = ttkb.LabelFrame(self, text="连接配置", padding=10)
        config_frame.pack(fill=X, padx=10, pady=5)

        # 协议和模式选择
        mode_frame = ttkb.Frame(config_frame)
        mode_frame.pack(fill=X, pady=5)

        ttkb.Label(mode_frame, text="协议:").pack(side=LEFT, padx=5)
        self.protocol_var = ttkb.StringVar(value="TCP")
        ttkb.Radiobutton(mode_frame, text="TCP", variable=self.protocol_var, value="TCP",
                         command=self._on_protocol_change).pack(side=LEFT, padx=5)
        ttkb.Radiobutton(mode_frame, text="UDP", variable=self.protocol_var, value="UDP",
                         command=self._on_protocol_change).pack(side=LEFT, padx=5)

        ttkb.Label(mode_frame, text="模式:").pack(side=LEFT, padx=5)
        self.mode_var = ttkb.StringVar(value="Server")
        ttkb.Radiobutton(mode_frame, text="Server", variable=self.mode_var, value="Server",
                         command=self._on_mode_change).pack(side=LEFT, padx=5)
        ttkb.Radiobutton(mode_frame, text="Client", variable=self.mode_var, value="Client",
                         command=self._on_mode_change).pack(side=LEFT, padx=5)

        # 网络参数配置
        param_frame = ttkb.Frame(config_frame)
        param_frame.pack(fill=X, pady=5)

        ttkb.Label(param_frame, text="IP地址:").pack(side=LEFT, padx=5)
        self.ip_var = ttkb.StringVar(value="127.0.0.1")
        self.ip_entry = ttkb.Entry(param_frame, textvariable=self.ip_var, width=15)
        self.ip_entry.pack(side=LEFT, padx=5)

        ttkb.Label(param_frame, text="端口:").pack(side=LEFT, padx=5)
        self.port_var = ttkb.StringVar(value="8080")
        ttkb.Entry(param_frame, textvariable=self.port_var, width=8).pack(side=LEFT, padx=5)

        self.conn_btn = ttkb.Button(param_frame, text="启动服务", command=self._toggle_connection, bootstyle=SUCCESS)
        self.conn_btn.pack(side=LEFT, padx=5)

        ttkb.Button(param_frame, text="清空连接", command=self._clear_connections, bootstyle=WARNING).pack(side=LEFT,
                                                                                                           padx=5)

        # 中间区域：左侧客户端列表，右侧接收日志
        middle_frame = ttkb.Frame(self)
        middle_frame.pack(fill=BOTH, expand=True, padx=10, pady=5)

        # 左侧：已连接IP列表（客户端连接管理）
        self.clients_frame = ttkb.LabelFrame(middle_frame, text="已连接客户端", padding=10)
        self.clients_frame.pack(side=LEFT, fill=Y, padx=(0, 5))

        # 客户端列表Treeview
        columns = ("id", "ip", "port", "time", "protocol")
        self.client_list = ttkb.Treeview(
            self.clients_frame,
            columns=columns,
            show="headings",
            height=8
        )

        # 设置列标题和宽度
        self.client_list.heading("id", text="ID")
        self.client_list.heading("ip", text="IP地址")
        self.client_list.heading("port", text="端口")
        self.client_list.heading("time", text="连接时间")
        self.client_list.heading("protocol", text="协议")

        self.client_list.column("id", width=40)
        self.client_list.column("ip", width=80)
        self.client_list.column("port", width=50)
        self.client_list.column("time", width=140)
        self.client_list.column("protocol", width=60)

        self.client_list.pack(fill=X, pady=5)

        # 客户端操作按钮
        client_btn_frame = ttkb.Frame(self.clients_frame)
        client_btn_frame.pack(fill=X, pady=5)

        ttkb.Button(
            client_btn_frame,
            text="断开选中",
            command=self._disconnect_selected_client,
            bootstyle=DANGER,
            width=10
        ).pack(side=LEFT, padx=5)

        ttkb.Button(
            client_btn_frame,
            text="发送到选中",
            command=self._send_to_selected_client,
            bootstyle=PRIMARY,
            width=10
        ).pack(side=LEFT, padx=5)

        # 右侧：接收日志
        receive_frame = ttkb.LabelFrame(middle_frame, text="接收日志", padding=10)
        receive_frame.pack(side=RIGHT, fill=BOTH, expand=True, padx=(5, 0))

        self.receive_text = ScrolledText(receive_frame, wrap=WORD, height=12)
        self.receive_text.pack(fill=BOTH, expand=True)

        # 接收控制
        receive_ctrl_frame = ttkb.Frame(receive_frame)
        receive_ctrl_frame.pack(fill=X, pady=5)

        self.timestamp_var = ttkb.BooleanVar(value=True)
        ttkb.Checkbutton(receive_ctrl_frame, text="显示时间戳", variable=self.timestamp_var).pack(side=LEFT, padx=5)

        self.hex_receive_var = ttkb.BooleanVar(value=False)
        ttkb.Checkbutton(receive_ctrl_frame, text="十六进制显示", variable=self.hex_receive_var).pack(side=LEFT, padx=5)

        ttkb.Button(receive_ctrl_frame, text="清空日志", command=self._clear_receive).pack(side=RIGHT, padx=5)

        # 底部发送区域
        send_frame = ttkb.LabelFrame(self, text="发送区", padding=10)
        send_frame.pack(fill=BOTH, expand=True, padx=10, pady=5)

        # 发送模式选择
        send_mode_frame = ttkb.Frame(send_frame)
        send_mode_frame.pack(fill=X, pady=5)

        self.send_mode_var = ttkb.StringVar(value="single")
        ttkb.Radiobutton(send_mode_frame,
                         text="单条发送",
                         variable=self.send_mode_var,
                         value="single").pack(side=LEFT, padx=10)
        ttkb.Radiobutton(send_mode_frame,
                         text="多条发送",
                         variable=self.send_mode_var,
                         value="multi").pack(side=LEFT, padx=10)

        # 发送目标选择（仅服务器模式可见）
        self.send_target_frame = ttkb.Frame(send_mode_frame)
        self.send_target_var = ttkb.StringVar(value="selected")
        ttkb.Radiobutton(self.send_target_frame,
                         text="发送到所有",
                         variable=self.send_target_var,
                         value="all").pack(side=LEFT, padx=10)
        ttkb.Radiobutton(self.send_target_frame,
                         text="发送到选中",
                         variable=self.send_target_var,
                         value="selected").pack(side=LEFT, padx=10)
        self.send_target_frame.pack(side=LEFT, padx=10)

        # 发送内容
        self.send_text = ScrolledText(send_frame, wrap=WORD, height=5)
        self.send_text.pack(fill=BOTH, expand=True, pady=5)
        self.send_text.insert(END, "Hello, World!")

        # 发送控制
        send_ctrl_frame = ttkb.Frame(send_frame)
        send_ctrl_frame.pack(fill=X, pady=5)

        # 定时发送
        ttkb.Label(send_ctrl_frame, text="定时发送(ms):").pack(side=LEFT, padx=5)
        self.interval_var = ttkb.StringVar(value="1000")
        ttkb.Entry(send_ctrl_frame, textvariable=self.interval_var, width=10).pack(side=LEFT, padx=5)

        self.hex_send_var = ttkb.BooleanVar(value=False)
        ttkb.Checkbutton(send_ctrl_frame, text="十六进制发送", variable=self.hex_send_var).pack(side=LEFT, padx=5)

        self.append_crlf_var = ttkb.BooleanVar(value=True)
        ttkb.Checkbutton(send_ctrl_frame, text="自动添加换行", variable=self.append_crlf_var).pack(side=LEFT, padx=5)

        ttkb.Button(send_ctrl_frame, text="发送", command=self._send_data).pack(side=RIGHT, padx=5)
        self.periodic_btn = ttkb.Button(send_ctrl_frame,
                                        text="定时发送",
                                        command=self._toggle_periodic_send,
                                        bootstyle=WARNING)
        self.periodic_btn.pack(side=RIGHT, padx=5)
        ttkb.Button(send_ctrl_frame, text="清空", command=self._clear_send).pack(side=RIGHT, padx=5)

        # 状态显示
        self.status_var = ttkb.StringVar(value="就绪")
        status_bar = ttkb.Label(self, textvariable=self.status_var, bootstyle=INFO, anchor=W)
        status_bar.pack(side=BOTTOM, fill=X, padx=10, pady=5)

        # 绑定客户端列表选择事件
        self.client_list.bind("<<TreeviewSelect>>", self._on_client_selected)

        # 初始UI状态更新
        self._on_mode_change()

    def _on_protocol_change(self):
        """协议变更处理"""
        self._update_ui_state()
        self._add_receive_log(f"已切换到{self.protocol_var.get()}协议")

    def _on_mode_change(self):
        """模式变更处理"""
        self._update_ui_state()
        # 服务器模式显示客户端列表和发送目标选择，客户端模式隐藏
        if self.mode_var.get() == "Server":
            self.clients_frame.pack(side=LEFT, fill=Y, padx=(0, 5))
            self.send_target_frame.pack(side=LEFT, padx=10)
            self.ip_entry.config(state=NORMAL)
            self.conn_btn.config(text="启动服务")
        else:
            self.clients_frame.pack_forget()
            self.send_target_frame.pack_forget()
            self.ip_entry.config(state=NORMAL)
            self.conn_btn.config(text="连接服务器")
        self._add_receive_log(f"已切换到{self.mode_var.get()}模式")

    def _update_ui_state(self):
        """更新UI状态"""
        is_active = self.is_connected or self.is_running

        # 连接状态下禁用配置修改
        self.ip_entry.config(state=DISABLED if is_active else NORMAL)
        self.port_var.set(self.port_var.get())  # 冻结端口输入

        # 客户端列表交互状态
        for btn in self.clients_frame.winfo_children():
            if isinstance(btn, ttkb.Frame):
                for child in btn.winfo_children():
                    if isinstance(child, ttkb.Button):
                        child.config(state=NORMAL if (is_active and self.mode_var.get() == "Server" and len(
                            self.clients) > 0) else DISABLED)

    def _on_client_selected(self, event):
        """客户端列表选择事件"""
        selection = self.client_list.selection()
        if selection:
            self.selected_client = self.client_list.item(selection[0], "values")[0]
            self._add_receive_log(f"已选择客户端: {self.selected_client}")
        else:
            self.selected_client = None

    def _toggle_connection(self):
        """切换连接/服务状态"""
        if self.mode_var.get() == "Server":
            if self.is_running:
                self._stop_server()
            else:
                self._start_server()
        else:  # Client
            if self.is_connected:
                self._disconnect_client()
            else:
                self._connect_client()

    def _start_server(self):
        """启动服务器"""
        try:
            ip = self.ip_var.get()
            port = int(self.port_var.get())

            # 创建socket
            if self.protocol_var.get() == "TCP":
                self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                self.socket.bind((ip, port))
                self.socket.listen(5)
                self._add_receive_log(f"TCP服务器已启动，监听 {ip}:{port}")
            else:  # UDP
                self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                self.socket.bind((ip, port))
                self._add_receive_log(f"UDP服务器已启动，监听 {ip}:{port}")

            self.is_running = True
            self.conn_btn.config(text="停止服务", bootstyle=DANGER)
            self.status_var.set(f"{self.protocol_var.get()}服务器运行中: {ip}:{port}")

            # 启动服务器监听线程
            threading.Thread(target=self._server_listen, daemon=True).start()
            self._update_ui_state()

        except Exception as e:
            self._add_receive_log(f"启动服务器失败: {str(e)}", is_error=True)

    def _stop_server(self):
        """停止服务器"""
        self.is_running = False
        if self.socket:
            try:
                self.socket.close()
            except Exception as e:
                self._add_receive_log(f"关闭服务器失败: {str(e)}", is_error=True)
            self.socket = None

        # 清理客户端连接
        self._clear_connections()

        self.conn_btn.config(text="启动服务", bootstyle=SUCCESS)
        self._add_receive_log(f"{self.protocol_var.get()}服务器已停止")
        self.status_var.set("就绪")
        self._update_ui_state()

    def _server_listen(self):
        """服务器监听线程"""
        if self.protocol_var.get() == "TCP":
            self._tcp_server_listen()
        else:
            self._udp_server_listen()

    def _tcp_server_listen(self):
        """TCP服务器监听"""
        while self.is_running:
            try:
                self.socket.settimeout(1.0)  # 设置超时以便检查退出信号
                client_socket, client_addr = self.socket.accept()
                client_id = str(uuid.uuid4())[:8]  # 生成短ID
                connect_time = datetime.now().strftime("%H:%M:%S")

                with self.client_lock:
                    self.clients[client_id] = (client_socket, client_addr, connect_time)
                    self._add_client_to_list(client_id, client_addr, connect_time)

                self._add_receive_log(f"TCP客户端 {client_addr[0]}:{client_addr[1]} 已连接 (ID: {client_id})")

                # 启动客户端处理线程
                threading.Thread(
                    target=self._handle_tcp_client,
                    args=(client_socket, client_addr, client_id),
                    daemon=True
                ).start()

            except socket.timeout:
                continue  # 超时继续循环，检查是否需要退出
            except Exception as e:
                if self.is_running:  # 只有在运行状态下才报告错误
                    self._add_receive_log(f"服务器错误: {str(e)}", is_error=True)
                break

    def _udp_server_listen(self):
        """UDP服务器监听"""
        while self.is_running:
            try:
                self.socket.settimeout(1.0)
                data, client_addr = self.socket.recvfrom(1024)

                # 检查客户端是否已存在
                client_id = None
                with self.client_lock:
                    for cid, (sock, addr, _) in self.clients.items():
                        if addr == client_addr:
                            client_id = cid
                            break

                # 新客户端，添加到列表
                if not client_id:
                    client_id = str(uuid.uuid4())[:8]
                    connect_time = datetime.now().strftime("%H:%M:%S")
                    with self.client_lock:
                        self.clients[client_id] = (self.socket, client_addr, connect_time)
                        self._add_client_to_list(client_id, client_addr, connect_time)
                    self._add_receive_log(f"UDP客户端 {client_addr[0]}:{client_addr[1]} 已连接 (ID: {client_id})")

                self.receive_queue.put((data, client_addr, client_id))

            except socket.timeout:
                continue
            except Exception as e:
                if self.is_running:
                    self._add_receive_log(f"服务器错误: {str(e)}", is_error=True)
                break

    def _handle_tcp_client(self, client_socket, client_addr, client_id):
        """处理TCP客户端连接"""
        while self.is_running:
            try:
                client_socket.settimeout(1.0)
                data = client_socket.recv(1024)
                if not data:
                    break  # 客户端断开连接

                self.receive_queue.put((data, client_addr, client_id))

            except socket.timeout:
                continue
            except Exception as e:
                self._add_receive_log(f"客户端 {client_id} 错误: {str(e)}", is_error=True)
                break

        # 客户端断开连接
        self._remove_client(client_id)
        self._add_receive_log(f"TCP客户端 {client_addr[0]}:{client_addr[1]} 已断开 (ID: {client_id})")

    def _connect_client(self):
        """客户端连接服务器"""
        try:
            ip = self.ip_var.get()
            port = int(self.port_var.get())

            # 创建socket
            if self.protocol_var.get() == "TCP":
                self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.socket.connect((ip, port))
                self._add_receive_log(f"TCP客户端已连接到 {ip}:{port}")

                # 启动接收线程
                threading.Thread(target=self._client_receive, daemon=True).start()
            else:  # UDP
                self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                self.server_addr = (ip, port)
                self._add_receive_log(f"UDP客户端已初始化，目标 {ip}:{port}")

            self.is_connected = True
            self.conn_btn.config(text="断开连接", bootstyle=DANGER)
            self.status_var.set(f"{self.protocol_var.get()}客户端已连接: {ip}:{port}")
            self._update_ui_state()

        except Exception as e:
            self._add_receive_log(f"连接服务器失败: {str(e)}", is_error=True)

    def _disconnect_client(self):
        """客户端断开连接"""
        self.is_connected = False
        if self.socket:
            try:
                self.socket.close()
            except Exception as e:
                self._add_receive_log(f"断开连接失败: {str(e)}", is_error=True)
            self.socket = None

        self.conn_btn.config(text="连接服务器", bootstyle=SUCCESS)
        self._add_receive_log(f"{self.protocol_var.get()}客户端已断开")
        self.status_var.set("就绪")
        self._update_ui_state()

    def _client_receive(self):
        """客户端接收线程"""
        while self.is_connected:
            try:
                self.socket.settimeout(1.0)
                data = self.socket.recv(1024)
                if not data:
                    break

                self.receive_queue.put((data, self.socket.getpeername(), "server"))

            except socket.timeout:
                continue
            except Exception as e:
                if self.is_connected:
                    self._add_receive_log(f"接收错误: {str(e)}", is_error=True)
                break

        # 连接已断开
        if self.is_connected:
            self.is_connected = False
            self._add_receive_log(f"{self.protocol_var.get()}连接已断开", is_error=True)
            self.conn_btn.config(text="连接服务器", bootstyle=SUCCESS)
            self.status_var.set("连接已断开")
            self._update_ui_state()

    def _send_data(self):
        """发送数据"""
        if (self.mode_var.get() == "Server" and not self.is_running) or \
                (self.mode_var.get() == "Client" and not self.is_connected):
            self._add_receive_log("未建立连接，请先启动服务或连接服务器", is_error=True)
            return

        try:
            # 获取发送内容
            send_mode = self.send_mode_var.get()
            if send_mode == "single":
                data = self.send_text.get("1.0", "1.0 lineend")  # 单行
            else:
                data = self.send_text.get("1.0", END)  # 多行

            # 清除末尾的换行符
            data = data.rstrip('\n').rstrip('\r')

            # 自动添加换行
            if self.append_crlf_var.get():
                data += '\r\n'

            # 十六进制发送处理
            if self.hex_send_var.get():
                # 移除所有空格
                data = data.replace(' ', '')
                # 转换为字节
                send_bytes = bytes.fromhex(data)
            else:
                # 字符串编码为字节
                send_bytes = data.encode('utf-8')

            # 根据模式和协议发送数据
            if self.mode_var.get() == "Server":
                # 服务器模式
                if self.send_target_var.get() == "selected" and self.selected_client:
                    # 发送给选中的客户端
                    self._send_to_client(self.selected_client, send_bytes)
                    self._add_receive_log(f"已发送到客户端 {self.selected_client}，长度: {len(send_bytes)} 字节",
                                          is_send=True)
                else:
                    # 发送给所有客户端
                    with self.client_lock:
                        if not self.clients:
                            self._add_receive_log("没有连接的客户端", is_error=True)
                            return

                        for client_id in list(self.clients.keys()):
                            self._send_to_client(client_id, send_bytes)

                    self._add_receive_log(f"已发送到所有客户端，长度: {len(send_bytes)} 字节", is_send=True)
            else:  # Client
                # 客户端模式，发送到服务器
                if self.protocol_var.get() == "TCP":
                    self.socket.send(send_bytes)
                else:  # UDP
                    self.socket.sendto(send_bytes, self.server_addr)

                self._add_receive_log(f"已发送到服务器，长度: {len(send_bytes)} 字节", is_send=True)

            # 显示发送的内容
            if self.hex_send_var.get():
                hex_str = ' '.join([f'{b:02X}' for b in send_bytes])
                self._add_receive_log(f"发送内容: {hex_str} (HEX)", is_send=True)
            else:
                self._add_receive_log(f"发送内容: {data}", is_send=True)

        except Exception as e:
            self._add_receive_log(f"发送失败: {str(e)}", is_error=True)

    def _send_to_selected_client(self):
        """发送到选中的客户端"""
        if not self.selected_client:
            self._add_receive_log("请先选择一个客户端", is_error=True)
            return
        self.send_target_var.set("selected")
        self._send_data()

    def _send_to_client(self, client_id, data):
        """发送数据到指定客户端"""
        try:
            with self.client_lock:
                if client_id not in self.clients:
                    return
                sock, addr, _ = self.clients[client_id]

            if self.protocol_var.get() == "TCP":
                sock.send(data)
            else:  # UDP
                sock.sendto(data, addr)

        except Exception as e:
            self._add_receive_log(f"发送到客户端 {client_id} 失败: {str(e)}", is_error=True)
            self._remove_client(client_id)  # 发送失败，移除客户端

    def _toggle_periodic_send(self):
        """切换定时发送状态"""
        if self.is_sending_periodically:
            # 停止定时发送
            self.is_sending_periodically = False
            self.periodic_btn.config(text="定时发送", bootstyle=WARNING)
            self._add_receive_log("已停止定时发送")
        else:
            # 开始定时发送
            try:
                interval = int(self.interval_var.get())
                if interval <= 0:
                    raise ValueError("间隔必须大于0")

                self.is_sending_periodically = True
                self.periodic_btn.config(text="停止发送", bootstyle=DANGER)
                self._add_receive_log(f"开始定时发送，间隔 {interval}ms")

                # 启动定时发送线程
                def periodic_send():
                    while self.is_sending_periodically and \
                            ((self.mode_var.get() == "Server" and self.is_running) or \
                             (self.mode_var.get() == "Client" and self.is_connected)):
                        self._send_data()
                        time.sleep(interval / 1000.0)

                threading.Thread(target=periodic_send, daemon=True).start()

            except ValueError as e:
                self._add_receive_log(f"定时发送设置错误: {str(e)}", is_error=True)
            except Exception as e:
                self._add_receive_log(f"启动定时发送失败: {str(e)}", is_error=True)
                self.is_sending_periodically = False

    def _check_receive_queue(self):
        """检查接收队列并更新UI"""
        while not self.receive_queue.empty():
            item = self.receive_queue.get()
            if len(item) == 3:
                data, addr, client_id = item
                self._process_received_data(data, addr, client_id)
            else:
                data, addr = item
                self._process_received_data(data, addr, "unknown")
            self.receive_queue.task_done()

        # 定期检查
        self.after(100, self._check_receive_queue)

    def _process_received_data(self, data, addr, client_id):
        """处理接收到的数据"""
        addr_str = f"{addr[0]}:{addr[1]}"
        client_info = f" (客户端 {client_id})" if client_id and client_id != "unknown" else ""

        if self.hex_receive_var.get():
            # 十六进制显示
            hex_str = ' '.join([f'{b:02X}' for b in data])
            self._add_receive_log(f"从 {addr_str}{client_info} 接收: {hex_str} (HEX)")
        else:
            # 字符串显示
            try:
                text = data.decode('utf-8')
                self._add_receive_log(f"从 {addr_str}{client_info} 接收: {text}")
            except UnicodeDecodeError:
                # 解码失败时显示十六进制
                hex_str = ' '.join([f'{b:02X}' for b in data])
                self._add_receive_log(f"从 {addr_str}{client_info} 接收: {hex_str} (无法解码为UTF-8)")

    def _add_client_to_list(self, client_id, addr, connect_time):
        """添加客户端到列表"""
        self.client_list.insert("", END, values=(
            client_id,
            addr[0],
            addr[1],
            connect_time,
            self.protocol_var.get()
        ))
        self._update_ui_state()

    def _remove_client(self, client_id):
        """从列表移除客户端"""
        with self.client_lock:
            if client_id in self.clients:
                # 关闭客户端socket
                sock, _, _ = self.clients[client_id]
                try:
                    if self.protocol_var.get() == "TCP":
                        sock.close()
                except:
                    pass

                del self.clients[client_id]

        # 从UI中移除
        for item in self.client_list.get_children():
            if self.client_list.item(item, "values")[0] == client_id:
                self.client_list.delete(item)
                break

        # 如果移除的是选中的客户端，清除选择
        if self.selected_client == client_id:
            self.selected_client = None

        self._update_ui_state()

    def _disconnect_selected_client(self):
        """断开选中的客户端连接"""
        if not self.selected_client:
            self._add_receive_log("请先选择一个客户端", is_error=True)
            return

        client_id = self.selected_client
        self._add_receive_log(f"断开客户端 {client_id} 连接")
        self._remove_client(client_id)

    def _clear_connections(self):
        """清除所有客户端连接"""
        if self.mode_var.get() == "Server" and self.is_running:
            with self.client_lock:
                client_ids = list(self.clients.keys())

            for client_id in client_ids:
                self._remove_client(client_id)

            self._add_receive_log("已清除所有客户端连接")
            self.selected_client = None

    def _add_receive_log(self, message, is_error=False, is_send=False):
        """添加接收日志"""
        # 获取当前时间戳
        timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3]

        # 格式化消息
        if self.timestamp_var.get():
            log_message = f"[{timestamp}] {message}\n"
        else:
            log_message = f"{message}\n"

        # 更新UI
        # self.receive_text.config(state=NORMAL)

        # 根据消息类型设置颜色
        if is_error:
            self.receive_text.insert(END, log_message, "error")
        elif is_send:
            self.receive_text.insert(END, log_message, "send")
        else:
            self.receive_text.insert(END, log_message, "receive")

        # 自动滚动到底部
        self.receive_text.see(END)
        # self.receive_text.config(state=DISABLED)

        # 配置标签样式
        self.receive_text.tag_config("error", foreground="#ff4444")
        self.receive_text.tag_config("send", foreground="#4CAF50")
        self.receive_text.tag_config("receive", foreground="#33b5e5")

    def _clear_receive(self):
        """清空接收区"""
        # self.receive_text.config(state=NORMAL)
        self.receive_text.delete("1.0", END)
        # self.receive_text.config(state=DISABLED)

    def _clear_send(self):
        """清空发送区"""
        self.send_text.delete("1.0", END)

    def on_close(self):
        """窗口关闭时的处理"""
        self.is_sending_periodically = False
        self.is_running = False
        self.is_connected = False

        if self.socket:
            try:
                self.socket.close()
            except:
                pass

        self.destroy()

    def create_widgets(self):
        pass
